const express = require('express');
const cheerio = require('cheerio');
const cors = require('cors');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json({ limit: '10mb' }));
app.use(express.static(path.join(__dirname, 'public')));

// 提取属性值函数
function extractAttribute($element, selector) {
    if (selector.includes('@')) {
        const parts = selector.split('@');
        const elementSelector = parts[0];
        const attrName = parts[1];
        const $target = elementSelector ? $element.find(elementSelector).first() : $element;
        return $target.attr(attrName) || '';
    }
    return $element.text().trim();
}

// API端点 - HTML内容提取
app.post('/api/extract', (req, res) => {
    try {
        const { html, selector, attribute, extractBoth = false, tableFormat = false } = req.body;

        // 验证输入
        if (!html) {
            return res.status(400).json({
                success: false,
                error: 'HTML内容不能为空'
            });
        }

        if (!selector) {
            return res.status(400).json({
                success: false,
                error: '选择器不能为空'
            });
        }

        // 加载HTML
        const $ = cheerio.load(html);
        
        // 分割多个选择器
        const selectors = selector.split('|').map(s => s.trim()).filter(s => s);
        
        // 分割多个属性（如果提供了）
        const attributes = attribute ? attribute.split('|').map(a => a.trim()).filter(a => a) : [];
        
        // 确保选择器和属性数量匹配（除非是同时提取模式）
        if (attributes.length > 0 && attributes.length !== selectors.length && !extractBoth) {
            return res.status(400).json({
                success: false,
                error: '选择器和属性数量必须匹配'
            });
        }
        
        let results = [];
        
        if (extractBoth) {
            // 同时提取属性和文本模式
            results = selectors.map((sel, index) => {
                const elements = $(sel);
                return elements.map((i, el) => {
                    const $element = $(el);
                    const attrValue = attributes[index] ? ($element.attr(attributes[index]) || '') : '';
                    const textValue = $element.text().trim();
                    return `${attrValue}\t${textValue}`;
                }).get();
            });
        } else {
            // 原有模式：要么提取属性，要么提取文本
            results = selectors.map((sel, index) => {
                const elements = $(sel);
                return elements.map((i, el) => {
                    const $element = $(el);
                    if (attributes.length > 0 && attributes[index]) {
                        // 提取属性值
                        return $element.attr(attributes[index]) || '';
                    } else {
                        // 提取文本内容
                        return extractAttribute($element, sel);
                    }
                }).get();
            });
        }

        // 检查是否有结果
        if (results.some(arr => arr.length === 0)) {
            return res.status(400).json({
                success: false,
                error: '某些选择器没有找到匹配的元素'
            });
        }

        // 准备响应数据
        const response = {
            success: true,
            data: results,
            metadata: {
                selectors: selectors,
                resultsCount: results.map(arr => arr.length),
                totalElements: results.reduce((sum, arr) => sum + arr.length, 0)
            }
        };

        // 如果需要表格格式，添加表格数据
        if (tableFormat) {
            const rowCount = Math.max(...results.map(arr => arr.length));
            const tableData = [];
            
            for (let i = 0; i < rowCount; i++) {
                const row = [];
                selectors.forEach((_, colIndex) => {
                    row.push(results[colIndex][i] || '');
                });
                tableData.push(row);
            }
            
            response.tableData = tableData;
        }

        res.json(response);

    } catch (error) {
        console.error('提取错误:', error);
        res.status(500).json({
            success: false,
            error: '提取过程中发生错误: ' + error.message
        });
    }
});

// 健康检查端点
app.get('/api/health', (req, res) => {
    res.json({ 
        success: true, 
        message: 'HTML提取器API服务运行正常',
        timestamp: new Date().toISOString()
    });
});

// API使用说明
app.get('/api', (req, res) => {
    res.json({
        name: 'HTML文本提取器API',
        version: '1.0.0',
        endpoints: {
            '/api/extract': {
                method: 'POST',
                description: '提取HTML内容',
                parameters: {
                    html: 'HTML源代码字符串',
                    selector: 'jQuery选择器（多个用|分隔）',
                    attribute: '属性名（可选，多个用|分隔）',
                    extractBoth: '是否同时提取属性和文本（可选，默认false）',
                    tableFormat: '是否返回表格格式数据（可选，默认false）'
                }
            },
            '/api/health': {
                method: 'GET',
                description: '服务健康检查'
            }
        },
        examples: {
            curl: `curl -X POST http://localhost:${PORT}/api/extract \\\\
  -H "Content-Type: application/json" \\\\
  -d '{
    "html": "<div><p>示例文本</p><a href=\\"https://example.com\\">链接</a></div>",
    "selector": "p | a",
    "attribute": " | href",
    "extractBoth": true,
    "tableFormat": true
  }'`
        }
    });
});

// 提供前端页面
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// 启动服务器
app.listen(PORT, () => {
    console.log(`🚀 HTML文本提取器服务已启动`);
    console.log(`📍 Web界面: http://localhost:${PORT}`);
    console.log(`📍 API端点: http://localhost:${PORT}/api/extract`);
    console.log(`📍 健康检查: http://localhost:${PORT}/api/health`);
});

// 优雅关闭
process.on('SIGINT', () => {
    console.log('\n🛑 正在关闭服务...');
    process.exit(0);
});
